PulumiのGet Started with AWSを試してみた
こんにちは!DA(データアナリティクス)事業本部 サービスソリューション部の大高です。
マルチクラウドに対応した Infrastructure as Code のツールとしては、弊社内ではTerraformのユーザが多いと思われます。一方で、最近同様のツールとしてPulumiというツールを知ったので、今回はこちらを試してみたいと思います。
なお、既に以下のエントリで同様の「やってみた」が公開されています。
やりたいこと
以下の公式ドキュメントに記載されている「Get Started with Pulumi」の「Get Started with AWS」に沿って進めていきたいと思います。
こちらでは簡単なリソースの作成から、変更、削除までの流れを試すことができます。
前提条件
実施する環境として、OSはMacOSを利用し、Nodeも事前に導入済みです。
% node -v v16.14.2
また、AWSアカウントで s3:CreateBucket
ポリシーが付与されている「Pulumi用のIAMユーザ」を作成しており、アクセスキーを発行済みの状態です。
AWS CLIも導入しており、上記のIAMユーザのアクセスキー、シークレットキーを設定したprofileとしてpulumi
を作成済みです。
Get Started with Pulumi
では、実際にドキュメントに従って始めていきます。
Before You Begin
Install Pulumi
まずはPulumiのインストールです。Homwbrew経由でのインストールなので特に問題ありません。
% brew install pulumi % pulumi version v3.27.0
Install Language Runtime
今回はTypeScript
で試したいと思いますので、Node.jsのインストールが必要となります。
こちらは「前提条件」に記載のとおり事前に導入済みなので詳細はスキップしますが、私はanyenvを利用して導入しています。
% node -v v16.14.2
Configure Pulumi to access your AWS account
このGet Startedでは s3:CreateBucket
のポリシーが付与されたIAM Userが必要となります。こちらは「前提条件」に記載のとおり事前に作成済みです。
設定についてはprofileを利用したいので、ここでは設定をスキップして後述のプロジェクト作成が済んでから実施します。
Pulumiのアカウント作成とトークンの発行
ドキュメントには記載がありませんが、後で利用するので「Pulumiのアカウント作成」と「トークンの発行」を実施しておきます。
下記のページの「Create an account」からアカウントを作成します。
2022/03/30現在では、GitHub、GitLab、Atlassian、Emailのいずれかからアカウント作成が可能でした。
ユーザーを作成したら、下記のアクセストークン発行ページのURLにアクセスし「Create token」からトークンを発行します。
- {USERNAME} - Settings | Pulumi
Create a New Project
では、事前準備ができたのでプロジェクトを作成していきます。
以下のとおりディレクトリを作成して、プロジェクトの初期化を行います。初期化時には先程作成したアクセストークンを聞かれるので、入力をして進めます。
% mkdir quickstart && cd quickstart % pulumi new aws-typescript Manage your Pulumi stacks by logging in. Run `pulumi login --help` for alternative login options. Enter your access token from https://app.pulumi.com/account/tokens or hit <ENTER> to log in using your browser : #←ここでトークンを入れる Welcome to Pulumi! Pulumi helps you create, deploy, and manage infrastructure on any cloud using your favorite language. You can get started today with Pulumi at: https://www.pulumi.com/docs/get-started/ Tip of the day: Resources you create with Pulumi are given unique names (a randomly generated suffix) by default. To learn more about auto-naming or customizing resource names see https://www.pulumi.com/docs/intro/concepts/resources/#autonaming.
続けて、プロジェクトの設定を入力していきます。基本的にはそのままENTERで進めますが、AWS Regionの設定だけはap-northeast-1
を指定しました。
This command will walk you through creating a new Pulumi project. Enter a value or leave blank to accept the (default), and press <ENTER>. Press ^C at any time to quit. project name: (quickstart) project description: (A minimal AWS TypeScript Pulumi program) Created project 'quickstart' Please enter your desired stack name. To create a stack in an organization, use the format <org-name>/<stack-name> (e.g. `acmecorp/dev`). stack name: (dev) Created stack 'dev' aws:region: The AWS region to deploy into: (us-east-1) ap-northeast-1 Saved config
あとはインストールが進むのを待ちます。
Installing dependencies... added 125 packages, and audited 126 packages in 30s 32 packages are looking for funding run `npm fund` for details found 0 vulnerabilities Finished installing dependencies Your new project is ready to go! ✨ To perform an initial deployment, run 'pulumi up'
完了しました。
AWS CLIのProfileをPulumiに設定する
追加作業として、以下のコマンドを実行してprofileを設定しておきます。
こちらでは事前に作成したpulumi
というAWS CLI用のprofileを利用して設定をすすめます。以下に記載のとおりコマンドを利用することで設定が可能です。
% pulumi config set aws:profile pulumi Please choose a stack, or create a new one: dev
Review the New Project
以下の3つのファイルが作成され、yamlファイルは想定どおりの設定になっていることを確認します。
- Pulumi.yaml
- Pulumi.dev.yaml
- index.ts
設定ファイルは以下のようになっていました。
name: quickstart runtime: nodejs description: A minimal AWS TypeScript Pulumi program
config: aws:profile: pulumi aws:region: ap-northeast-1
また、リソース構築用のスクリプトは以下のようになっています。
import * as pulumi from "@pulumi/pulumi"; import * as aws from "@pulumi/aws"; import * as awsx from "@pulumi/awsx"; // Create an AWS resource (S3 Bucket) const bucket = new aws.s3.Bucket("my-bucket"); // Export the name of the bucket export const bucketName = bucket.id;
今回、バケット名だけ変更してみます。
import * as pulumi from "@pulumi/pulumi"; import * as aws from "@pulumi/aws"; import * as awsx from "@pulumi/awsx"; // Create an AWS resource (S3 Bucket) const bucket = new aws.s3.Bucket("cm-ootaka-get-started-with-pulumi"); // Export the name of the bucket export const bucketName = bucket.id;
Deploy the Stack
準備ができたのでデプロイに進みます。
以下のpulumi up
コマンドを実行することで、何が作成されるかを表示されます。
% pulumi up Previewing update (dev) View Live: https://app.pulumi.com/ootaka-daisuke/quickstart/dev/previews/e70c40f7-3855-481e-a366-f767c28807af Type Name Plan + pulumi:pulumi:Stack quickstart-dev create + └─ aws:s3:Bucket cm-ootaka-get-started-with-pulumi create Resources: + 2 to create Do you want to perform this update? [Use arrows to move, enter to select, type to filter] yes > no details
問題がなければカーソルをyes
に合わせて続けます。
Do you want to perform this update? yes Updating (dev) View Live: https://app.pulumi.com/ootaka-daisuke/quickstart/dev/updates/1 Type Name Status + pulumi:pulumi:Stack quickstart-dev created + └─ aws:s3:Bucket cm-ootaka-get-started-with-pulumi created Outputs: bucketName: "cm-ootaka-get-started-with-pulumi-484d188" Resources: + 2 created Duration: 6s
S3バケットが作成されました!なお、作成したリソースはOutputs
に表示されており、以下のコマンドでも確認できます。
% pulumi stack output bucketName cm-ootaka-get-started-with-pulumi-484d188
Modify the Program
次に、プログラムを修正して静的サイトホスティングができるようにしていきます。
まずは以下のようなindex.html
ファイルを追加します。
<html> <body> <h1>Hello, Pulumi!</h1> </body> </html>
ファイルを追加したので、プログラムもこのファイルをS3バケットに配置するように修正します。
import * as pulumi from "@pulumi/pulumi"; import * as aws from "@pulumi/aws"; import * as awsx from "@pulumi/awsx"; // Create an AWS resource (S3 Bucket) const bucket = new aws.s3.Bucket("cm-ootaka-get-started-with-pulumi"); const bucketObject = new aws.s3.BucketObject("index.html", { bucket: bucket, source: new pulumi.asset.FileAsset("index.html"), }); // Export the name of the bucket export const bucketName = bucket.id;
Deploy the Changes
では、もう一度デプロイします。
index.htmlをデプロイする
% pulumi up Previewing update (dev) View Live: https://app.pulumi.com/ootaka-daisuke/quickstart/dev/previews/ac4bd4ff-8618-4192-a8a0-6d9d6b54ab67 Type Name Plan Info pulumi:pulumi:Stack quickstart-dev + └─ aws:s3:BucketObject index.html create 2 warnings Diagnostics: aws:s3:BucketObject (index.html): warning: urn:pulumi:dev::quickstart::aws:s3/bucketObject:BucketObject::index.html verification warning: Argument is deprecated warning: urn:pulumi:dev::quickstart::aws:s3/bucketObject:BucketObject::index.html verification warning: Argument is deprecated Do you want to perform this update? [Use arrows to move, enter to select, type to filter] yes > no details
yesを選択して適用します。(引数のdeprecatedについて警告が出ていますが、今回は無視します)
Do you want to perform this update? yes Updating (dev) View Live: https://app.pulumi.com/ootaka-daisuke/quickstart/dev/updates/2 Type Name Status Info pulumi:pulumi:Stack quickstart-dev + └─ aws:s3:BucketObject index.html created 2 warnings Diagnostics: aws:s3:BucketObject (index.html): warning: urn:pulumi:dev::quickstart::aws:s3/bucketObject:BucketObject::index.html verification warning: Argument is deprecated warning: urn:pulumi:dev::quickstart::aws:s3/bucketObject:BucketObject::index.html verification warning: Argument is deprecated Outputs: bucketName: "cm-ootaka-get-started-with-pulumi-484d188" Resources: + 1 created 2 unchanged Duration: 3s
実際にAWS CLIで確認もできます。
% aws s3 ls $(pulumi stack output bucketName) --profile pulumi 2022-03-31 11:29:28 69 index.html
ちゃんとファイルが置かれていますね。
静的サイトホスティングをする
続けて、改めて静的サイトホスティングがされるようにコードを修正していきます。
import * as pulumi from "@pulumi/pulumi"; import * as aws from "@pulumi/aws"; import * as awsx from "@pulumi/awsx"; // Create an AWS resource (S3 Bucket) const bucket = new aws.s3.Bucket("cm-ootaka-get-started-with-pulumi", { website: { indexDocument: "index.html", }, }); const bucketObject = new aws.s3.BucketObject("index.html", { acl: "public-read", contentType: "text/html", bucket: bucket, source: new pulumi.asset.FileAsset("index.html"), }); // Export the name of the bucket export const bucketName = bucket.id; export const bucketEndpoint = pulumi.interpolate`http://${bucket.websiteEndpoint}`;
バケットのインデックスファイルとしてindex.html
を指定し、パブリックアクセスを許可しました。
また、bucketEndpoint
としてウェブサイトにアクセスするためのエンドポイントURLを設定しています。
この状態で改めてデプロイします。
% pulumi up Previewing update (dev) View Live: https://app.pulumi.com/ootaka-daisuke/quickstart/dev/previews/156247be-b8c9-47e1-a3bf-91824cf27bf2 Type Name Plan Info pulumi:pulumi:Stack quickstart-dev ~ ├─ aws:s3:Bucket cm-ootaka-get-started-with-pulumi update [diff: +website] ~ └─ aws:s3:BucketObject index.html update [diff: ~acl,contentType]; 2 warnings Diagnostics: aws:s3:BucketObject (index.html): warning: urn:pulumi:dev::quickstart::aws:s3/bucketObject:BucketObject::index.html verification warning: Argument is deprecated warning: urn:pulumi:dev::quickstart::aws:s3/bucketObject:BucketObject::index.html verification warning: Argument is deprecated Outputs: + bucketEndpoint: output<string> Do you want to perform this update? [Use arrows to move, enter to select, type to filter] yes > no details
yes
を選択します。
Do you want to perform this update? yes Updating (dev) View Live: https://app.pulumi.com/ootaka-daisuke/quickstart/dev/updates/3 Type Name Status Info pulumi:pulumi:Stack quickstart-dev ~ ├─ aws:s3:Bucket cm-ootaka-get-started-with-pulumi updated [diff: +website] ~ └─ aws:s3:BucketObject index.html updated [diff: ~acl,contentType]; 2 warnings Diagnostics: aws:s3:BucketObject (index.html): warning: urn:pulumi:dev::quickstart::aws:s3/bucketObject:BucketObject::index.html verification warning: Argument is deprecated warning: urn:pulumi:dev::quickstart::aws:s3/bucketObject:BucketObject::index.html verification warning: Argument is deprecated Outputs: + bucketEndpoint: "http://cm-ootaka-get-started-with-pulumi-484d188.s3-website-ap-northeast-1.amazonaws.com" bucketName : "cm-ootaka-get-started-with-pulumi-484d188" Resources: ~ 2 updated 1 unchanged Duration: 4s
curlコマンドで確認してみましょう。
% curl $(pulumi stack output bucketEndpoint) <html> <body> <h1>Hello, Pulumi!</h1> </body> </html>
想定どおり、ホスティングされました!
Destroy the Stack
最後に後片付けをします。
以下のpulumi destroy
コマンドで作成したリソースを削除します。
% pulumi destroy Previewing destroy (dev) View Live: https://app.pulumi.com/ootaka-daisuke/quickstart/dev/previews/dbc054dc-fdf9-47f7-a4d7-762efdee664a Type Name Plan - pulumi:pulumi:Stack quickstart-dev delete - ├─ aws:s3:BucketObject index.html delete - └─ aws:s3:Bucket cm-ootaka-get-started-with-pulumi delete Outputs: - bucketEndpoint: "http://cm-ootaka-get-started-with-pulumi-484d188.s3-website-ap-northeast-1.amazonaws.com" - bucketName : "cm-ootaka-get-started-with-pulumi-484d188" Resources: - 3 to delete Do you want to perform this destroy? [Use arrows to move, enter to select, type to filter] yes > no details
yes
を選択します。
Do you want to perform this destroy? yes Destroying (dev) View Live: https://app.pulumi.com/ootaka-daisuke/quickstart/dev/updates/4 Type Name Status - pulumi:pulumi:Stack quickstart-dev deleted - ├─ aws:s3:BucketObject index.html deleted - └─ aws:s3:Bucket cm-ootaka-get-started-with-pulumi deleted Outputs: - bucketEndpoint: "http://cm-ootaka-get-started-with-pulumi-484d188.s3-website-ap-northeast-1.amazonaws.com" - bucketName : "cm-ootaka-get-started-with-pulumi-484d188" Resources: - 3 deleted Duration: 4s The resources in the stack have been deleted, but the history and configuration associated with the stack are still maintained. If you want to remove the stack completely, run 'pulumi stack rm dev'.
削除されました!
念の為、以下のコマンドで削除されているか確かめます。
% aws s3 ls cm-ootaka-get-started-with-pulumi-484d188 --profile pulumi An error occurred (NoSuchBucket) when calling the ListObjectsV2 operation: The specified bucket does not exist
ちゃんと削除されていますね。
おまけ
リソースの削除時に以下の表示がされていました。
The resources in the stack have been deleted, but the history and configuration associated with the stack are still maintained. If you want to remove the stack completely, run 'pulumi stack rm dev'.
実際に試してスタックを完全に削除してみます。
% pulumi stack rm dev This will permanently remove the 'dev' stack! Please confirm that this is what you'd like to do by typing ("dev"): dev Stack 'dev' has been removed!
削除されました。
実際に何が起きたかですが、まずPulumi.dev.yaml
ファイルが削除されました。また、Pulumiサービス上のquickstart
プロジェクトも削除されたことも確認できました。
Pulumi.dev.yaml
ファイルが削除されることには、ちょっと気をつけたいですね。
まとめ
以上、PulumiのGet Started with AWSを試してみました。
普段はCloudFormationを利用することが多いのですが、コードでインフラを構築できるのはとても快適ですね。また、今回は試していませんが複数のクラウド環境に同時にリソースをデプロイすることもできるので、今後機会があったら試してみたいと思います。
どなたかのお役に立てば幸いです。それでは!